package com.cloud.zuul.config;

import com.lwj.framework.aop.RoleAspect;
import com.lwj.framework.config.CacheConfiguration;
import com.lwj.framework.degest.DigestSignature;
import com.lwj.framework.mybatis.BaseMapper;
import com.lwj.framework.security.AuthFeignTemplate;
import com.lwj.framework.security.AuthRestTemplate;
import com.lwj.framework.security.auth.AuthRoleAspect;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import feign.RequestInterceptor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.lwj.logger.aop.LogAspect;
import org.lwj.logger.filter.LogFilter;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@EnableCaching
@Configuration
public class CommonConfig extends CacheConfiguration {
	@Value("${spring.application.name}")
	private String appname;

	@Value("${security.user.signing}")
	private String userSigning;

	@Bean
	public BaseMapper baseMapper(SqlSessionTemplate sqlSessionTemplate) {
		return new BaseMapper(sqlSessionTemplate);
	}

//	@Bean
//	public Sampler defaultSampler() {
//		return Sampler.ALWAYS_SAMPLE;
//	}

	@Bean
	public ServletRegistrationBean<HystrixMetricsStreamServlet> hystrixMetricsStreamServlet() {
		HystrixMetricsStreamServlet hystrixMetricsStreamServlet = new HystrixMetricsStreamServlet();
		ServletRegistrationBean<HystrixMetricsStreamServlet> servletRegistrationBean = new ServletRegistrationBean<HystrixMetricsStreamServlet>();
		servletRegistrationBean.setServlet(hystrixMetricsStreamServlet);
		servletRegistrationBean.addUrlMappings("/actuator/hystrix.stream");
		servletRegistrationBean.setName("HystrixMetricsStreamServlet");
		return servletRegistrationBean;
	}

	@Bean
	public DigestSignature digestSignature() {
		return new DigestSignature(userSigning);
	}

	@Bean
	public RoleAspect roleAspect() {
		return new AuthRoleAspect(digestSignature());
	}

	/*
	 * LogFilter
	 */
	@Bean
	public FilterRegistrationBean<LogFilter> registerAuthFilter() {
		LogFilter logFilter = new LogFilter();
		logFilter.setMaxLength(10000);
		String[] uriPatterns = { "*.dwr", "*.do", "*.action" };
		logFilter.setUriPatterns(uriPatterns);
		String[] excludeUriPatterns = { "*.html", "*.js" };
		logFilter.setExcludeUriPatterns(excludeUriPatterns);
		//
		FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<LogFilter>();
		registration.setFilter(logFilter);
		registration.addUrlPatterns("/*");
		registration.setName("logFilter");
		// 值越小，Filter越靠前。
		registration.setOrder(1);
		return registration;
	}

	/*
	 * 切面配置
	 */
	@Aspect
	private class LogAspectConfig extends LogAspect {

		@Around("@annotation(org.lwj.logger.api.LogMethod)")
		public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
			return super.logAround(pjp);
		}
	}

	/*
	 * 日志切面
	 */
	@Bean
	public LogAspectConfig logAspectConfig() {
		return new LogAspectConfig();
	}

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new AuthRestTemplate(appname, digestSignature());
	}

	@Bean
	public RequestInterceptor feignTemplate() {
		return new AuthFeignTemplate(appname, digestSignature());
	}

}
